/******************************************************************************

 @File         : playdemo.c
 @Author       : Conor Mac Aoidh, conormacaoidh@gmail.com
 @Brief        : Used for testing the realtime sonant synth
 Date          : 04/07/2012

This demo file runs the Realtime Sonant Synth. Usage:

./playdemo[.exe]

This file uses the RtAudio C++ Library along with the Realtime
Sonant Synth to render and play audio in realtime.

The song being synthesised is contained in a header file generated
by the Sonant Synth (http://www.pouet.net/prod.php?which=53615) and
included in sonant.c

Compilation notes:

I have tested with MinGW on Windows. In order to compile on UNIX and
other systems, you will most likely have to build rtaudio again and
alter the sonant Makefile.

******************************************************************************/

/******************************************************************************
	1: Include files
******************************************************************************/

#include "includes/rtaudio/RtAudio.h"
#include <iostream>
#include <cstdlib>
#include "sonant.c"

/******************************************************************************
	2: Defines
******************************************************************************/

#define FORMAT		RTAUDIO_SINT16

/******************************************************************************
	3: Global Veriables
******************************************************************************/

unsigned counter = 0;
short *left_buffer, *right_buffer;
RtAudio dac;

/******************************************************************************
	4: Functions Implementation
******************************************************************************/

// callback function for RtAudio - renders audio using Sonant_render
int render_callback(
	void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames,
	double streamTime, RtAudioStreamStatus status, void *data
){
	#ifdef DEBUG
			std::cout << std::endl << "main( ): running sonant " << counter++ << std::endl;
	#endif

	short *wave_buffer = (short*) outputBuffer;

	if( !Sonant_render( left_buffer, right_buffer ) ){
		std::cout << "streaming complete!" << std::endl;
		dac.stopStream( );
	}

	// copy left/right buffer into output buffer
	Sonant_merge( wave_buffer, left_buffer, right_buffer );

	// print first 2 pairs of left/right
	int i = 0;
	printf( "\n first 10 pairs\n" );
	for( i = 0; i < 10; ++i ){
		printf( "wave[ %d ] = 0x%08x\n", i, wave_buffer[ i ] );
	}

	if ( status )
		std::cout << "Stream underflow detected!" << std::endl;

	return 0;
}

// Usage ./playdemo.exe
int main( int argc, char *argv[] )
{
	unsigned bufferFrames, c = 0;
	char input;

	left_buffer  = (short*) malloc( sizeof( short ) * BUFF_SIZE );
	right_buffer = (short*) malloc( sizeof( short ) * BUFF_SIZE );

	// check for audio devices
	if ( dac.getDeviceCount() < 1 ) {
		std::cout << "\nNo audio devices found!\n";
		exit( 1 );
	}

	// Let RtAudio print messages to stderr.
	dac.showWarnings( true );

	// Set our stream parameters for output only.
	bufferFrames = BUFF_SIZE;
	RtAudio::StreamParameters oParams;
	oParams.deviceId = dac.getDefaultOutputDevice();
	oParams.nChannels = 2;
	oParams.firstChannel = 0;	

	// init sonant
	Sonant_init( );

	// open stream
	try {
		dac.openStream( &oParams, NULL, FORMAT, 44100, &bufferFrames, &render_callback, (void *) c );
		dac.startStream();
	}
	catch ( RtError& e ) {
		e.printMessage();
		exit( 0 );
	}

	// wait for user input
	std::cout << "Stream latency = " << dac.getStreamLatency() << "\n" << std::endl;
	std::cout << "\nPlaying ... press <enter> to quit (buffer size = " << bufferFrames << ").\n";
	std::cin.get( input );

	try { // stop the stream or throw error
		dac.stopStream();
	}
	catch( RtError& e ){
		e.printMessage();
	}

	// close stream
	if ( dac.isStreamOpen() )
		dac.closeStream();

	return 0;
}

/******************************************************************************
	End of file
******************************************************************************/
